package com.love.springboot.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * Druid数据库连接池配置文件
 */
@Configuration
@NacosPropertySource(dataId = "springboot-druid", autoRefreshed = true)
public class DruidConfig {
    private static final Logger logger = LoggerFactory.getLogger(DruidConfig.class);

    @NacosValue(value = "${spring.datasource.druid.url:}", autoRefreshed = true)
    private String dbUrl;

    @NacosValue(value = "${spring.datasource.druid.username:}", autoRefreshed = true)
    private String username;

    @NacosValue(value = "${spring.datasource.druid.password:}", autoRefreshed = true)
    private String password;

    @NacosValue(value = "${spring.datasource.druid.driverClassName:}", autoRefreshed = true)
    private String driverClassName;

    @NacosValue(value = "${spring.datasource.druid.initial-size:}", autoRefreshed = true)
    private int initialSize;

    @NacosValue(value = "${spring.datasource.druid.max-active:}", autoRefreshed = true)
    private int maxActive;

    @NacosValue(value = "${spring.datasource.druid.min-idle:}", autoRefreshed = true)
    private int minIdle;

    @NacosValue(value = "${spring.datasource.druid.max-wait:}", autoRefreshed = true)
    private int maxWait;

    @NacosValue(value = "${spring.datasource.druid.pool-prepared-statements:}", autoRefreshed = true)
    private boolean poolPreparedStatements;

    @NacosValue(value = "${spring.datasource.druid.max-pool-prepared-statement-per-connection-size:}", autoRefreshed = true)
    private int maxPoolPreparedStatementPerConnectionSize;

    @NacosValue(value = "${spring.datasource.druid.time-between-eviction-runs-millis:}", autoRefreshed = true)
    private int timeBetweenEvictionRunsMillis;

    @NacosValue(value = "${spring.datasource.druid.min-evictable-idle-time-millis:}", autoRefreshed = true)
    private int minEvictableIdleTimeMillis;

    @NacosValue(value = "${spring.datasource.druid.max-evictable-idle-time-millis:}", autoRefreshed = true)
    private int maxEvictableIdleTimeMillis;

    @NacosValue(value = "${spring.datasource.druid.validation-query:}", autoRefreshed = true)
    private String validationQuery;

    @NacosValue(value = "${spring.datasource.druid.test-while-idle:}", autoRefreshed = true)
    private boolean testWhileIdle;

    @NacosValue(value = "${spring.datasource.druid.test-on-borrow:}", autoRefreshed = true)
    private boolean testOnBorrow;

    @NacosValue(value = "${spring.datasource.druid.test-on-return:}", autoRefreshed = true)
    private boolean testOnReturn;

    @NacosValue(value = "${spring.datasource.druid.filters:}", autoRefreshed = true)
    private String filters;

    @NacosValue(value = "${{spring.datasource.druid.connection-properties}:}", autoRefreshed = true)
    private String connectionProperties;

    /**
     * Druid 连接池配置
     */
    @Bean     //声明其为Bean实例
    public DruidDataSource dataSource() {
        DruidDataSource datasource = new DruidDataSource();
        datasource.setUrl(dbUrl);
        datasource.setUsername(username);
        datasource.setPassword(password);
        datasource.setDriverClassName(driverClassName);
        datasource.setInitialSize(initialSize);
        datasource.setMinIdle(minIdle);
        datasource.setMaxActive(maxActive);
        datasource.setMaxWait(maxWait);
        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        datasource.setMaxEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        datasource.setValidationQuery(validationQuery);
        datasource.setTestWhileIdle(testWhileIdle);
        datasource.setTestOnBorrow(testOnBorrow);
        datasource.setTestOnReturn(testOnReturn);
        datasource.setPoolPreparedStatements(poolPreparedStatements);
        datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
        try {
            datasource.setFilters(filters);
        } catch (Exception e) {
            logger.error("druid configuration initialization filter", e);
        }
        datasource.setConnectionProperties(connectionProperties);
        return datasource;
    }

    /**
     * JDBC操作配置
     */
    @Bean(name = "dataOneTemplate")
    public JdbcTemplate jdbcTemplate(@Autowired DruidDataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

    /**
     * 配置 Druid 监控界面
     */
    @Bean
    public ServletRegistrationBean statViewServlet() {
        ServletRegistrationBean srb =
                new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        //设置控制台管理用户
        srb.addInitParameter("loginUsername", "root");
        srb.addInitParameter("loginPassword", "root");
        //是否可以重置数据
        srb.addInitParameter("resetEnable", "false");
        return srb;
    }

    @Bean
    public FilterRegistrationBean statFilter() {
        //创建过滤器
        FilterRegistrationBean frb =
                new FilterRegistrationBean(new WebStatFilter());
        //设置过滤器过滤路径
        frb.addUrlPatterns("/*");
        //忽略过滤的形式
        frb.addInitParameter("exclusions",
                "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return frb;
    }

}
